package objetos;

import interfaces.IGenericObject;

import java.util.ArrayList;
import java.util.List;

import util.Validador;


/**
 * 
 * @author  Filipe Alencar, Felipe Jos� F. Cavalcanti, Rodrigo L. de Brito, Thiago Gon�alves, Victor Hugo Arcelino.
 *
 */
public class Usuario implements IGenericObject{
	private String login;
	private String senha;
	private String endereco; 
	private String email;
	private String nome;
	private List<Item> listaDeItens = new ArrayList<Item>();
	private List<Usuario> listaDeAmigosAdicionados = new ArrayList<Usuario>();
	private List<Usuario> listaDeAmigosPendentes = new ArrayList<Usuario>();
	private int numeroDeEmprestimosRealizadosComoEmprestador = 0;
	private List<Emprestimo> listaEmprestimosDoBeneficiado = new ArrayList<Emprestimo>();
	private List<Emprestimo> listaEmprestimosDoEmprestador = new ArrayList<Emprestimo>();
	private List<Emprestimo> listaEmprestimosDeTodosStatus = new ArrayList<Emprestimo>();
	private List<Emprestimo> listaEmprestimosPendentes = new ArrayList<Emprestimo>();
	
	/**
	 * Cria um usuario.
	 * @param login Login do usuario.
	 * @param nome Nome do usuario.
	 * @param endereco Endereco do usuario.
	 * @throws Exception Se o login e nome forem vazios,null ou nao forem do tipo String.
	 */
	
	public Usuario(String login,String nome, String endereco) throws Exception{
		if(!(Validador.validarString(login)))
			throw new Exception("Login inválido");
		if(!(Validador.validarString(nome)))
			throw new Exception("Nome inválido");
		setLogin(login);
		setNome(nome);
		setEndereco(endereco);
		
	}
	
	
    /**
     * Captura o Nome do usuario
     * @return o nome
     */	
	public String getNome(){
		return this.nome;
	}
    /**
     * Captura a quantidade de emprestimos realizados
     * @return a quantidade de emprestimos
     */	
	public int getNumeroDeEmprestimosRealizados(){
		return numeroDeEmprestimosRealizadosComoEmprestador;
	}
	 /**
     * Captura o Endereco
     * @return endereco
     */	
	public String getEndereco(){
		return this.endereco;
		
	}
	
	 /**
     * Captura o Login
     * @return o login
     */	
	public String getLogin(){
		return this.login;
	}
	
	
    /**
     * Captura o E-mail
     * @return email
     */
	public String getEmail(){
		return this.email;
	}
    /**
     * Captura a lista de itens cadastrados do usuario
     * @return a lista
     */
	public List<Item> getListaDeItens() throws Exception{
		return this.listaDeItens;
	}
	/**
	 * Captura a lista de amigos adicionados 
	 * @return a lista
	 * @throws Exception Lista Vazia
	 */
	public List<Usuario> getListaDeAmigosAdicionados() throws Exception{
		return this.listaDeAmigosAdicionados;	
	}
	/**
	 * Captura a lista de amigos pendentes
	 * @return a lista
	 * @throws Exception Lista Vazia
	 */
	public List<Usuario> getListaDeAmigosPendentes() throws Exception{
		return this.listaDeAmigosPendentes;
	}
    /**
     * Permite mudar o nome
     * @param nome - nome 
     * @throws Exception - erro de nome vazio
     */
	public void setNome(String nome) throws Exception{
        if(nome.length()==0 )
            throw new Exception("O nome não deve ser vazio");
        this.nome = nome;
	}	
	/**
     *  Permite mudar o Endereco
     * @param endereco
     */
	public void setEndereco(String endereco){
		this.endereco = endereco;
	}
	 /**
     * Permite mudar o email
     * @param email
     * @throws Exception - Email digitado errado
     */
	public void setEmail(String email) throws Exception{
        if (!email.contains("@")||email.length()==0)
            throw new Exception("O email deve conter @ e ser maior que 3");
        this.email = email;
	}
	
	 /**
     * Permite mudar o login
     * @param email
     * @throws Exception - Login for vazio.
     */
	public void setLogin(String login) throws Exception{
		if(login.trim().isEmpty())
			throw new Exception("O login não poder ser vazio.");
		this.login = login;
			
		
	}
	/**
	 * Permite adicionar um item
	 * @param item
	 */
	public void setItens(Item item){
		this.listaDeItens.add(item);
	}
	
	/**
	 * Permite adicionar um amigo aceitos
	 * @param amigo
	 */
	public void aprovarAmizade(Usuario amigo){
		this.listaDeAmigosPendentes.remove(amigo);
		this.listaDeAmigosAdicionados.add(amigo);
	}
	
	/**
	 * Adiciona um item a lista de itens.
	 * @param item- Item a ser adicionado.
	 */
	public void adicionarItem(Item item){
		this.listaDeItens.add(item);
	}
	/**
	 * Adiciona um amigo.
	 * @param amigo - Amigo a ser adicionado
	 */
	public void adicionarAmigo(Usuario amigo){
		this.listaDeAmigosAdicionados.add(amigo);
	}
	/**
	 * Permite adicionar um amigo a lista de amigos esperando Aceitacao 
	 * @param amigo
	 * @throws Exception 
	 */
	public void adicionarAmizadePendente(Usuario amigo) throws Exception{
		if(this.listaDeAmigosAdicionados.contains(amigo))
			throw new Exception("Os usuários já são amigos");
		if(this.listaDeAmigosPendentes.contains(amigo))
			throw new Exception("Requisição já solicitada");
		this.listaDeAmigosPendentes.add(amigo);
	}
	/**
	 * Verifica se o usuario recebido no parametro é amigo.
	 * @param usuario - Usuario a se verificar.
	 * @return - true ou false.
	 */
	public boolean ehAmigo(Usuario usuario){
		if (this.listaDeAmigosAdicionados.contains(usuario))
			return true;
		return false;
	}
	/**
	 * Incrementa um emprestimo realizado para o usuario
	 */
	public void adicionaEmprestimoRealizado(){
		this.numeroDeEmprestimosRealizadosComoEmprestador++;
	}
	
	/**
	 * Adiciona um emprestimo a lista de emprestimo do usuario beneficiado.
	 */
	public void addEmprestimoDoBeneficiado(Emprestimo emprestimo){
		listaEmprestimosDoBeneficiado.add(emprestimo);
		listaEmprestimosDeTodosStatus.add(emprestimo);
	}
	
	
	/**
	 * Adiciona um emprestimo a lista de emprestimo do usuario beneficiado.
	 */
	public void addEmprestimoDoEmprestador(Emprestimo emprestimo){
		listaEmprestimosDoEmprestador.add(emprestimo);
		listaEmprestimosDeTodosStatus.add(emprestimo);
	}
	
	/**
	 * Permite adicionar um emprestimo a lista de emprestimos esperando aprovacao.
	 * @param e
	 */
	public void adicionarEmprestimoPendente(Emprestimo emprestimo) throws Exception{
		if(listaEmprestimosPendentes.contains(emprestimo)){
			throw new Exception("Requisição já solicitada");
		}
		listaEmprestimosPendentes.add(emprestimo);
		
	}
	
	/**
	 * O emprestimo eh aprovado deixando de ser pendente, e passando a fazer parte da lista de emprestimos do emprestador.
	 * @param emprestimo O emprestimo a ser a aprovado pelo emprestador.
	 * @throws Exception 
	 */
	public void aprovarEmprestimo(Emprestimo emprestimo) throws Exception{
		if(listaEmprestimosDoEmprestador.contains(emprestimo)){
			throw new Exception("Empréstimo já aprovado");
		}
		listaEmprestimosPendentes.remove(emprestimo);
		listaEmprestimosDoEmprestador.add(emprestimo);
		listaEmprestimosDeTodosStatus.add(emprestimo);
	}
	
	/**
	 * Modifica a senha do usuario para a senha escolhida.
	 * @param senha - A nova senha
	 */
	public void setSenha(String senha) {
		this.senha = senha;
	}
	
	/**
	 * Retorna a senha do usuario.
	 * @return
	 */
	public String getSenha() {
		return senha;
	}
	
	
	/**
	 * Retorna a lista de emprestimos do usuario beneficiado.
	 * @return A lista de emprestimos.
	 */
	public List<Emprestimo> getListaEmprestimosDoBeneficiado() {
		return listaEmprestimosDoBeneficiado;
	}
	
	/**
	 * Retorna a lista de emprestimos do usuario emprestador.
	 * @return A lista de emprestimos.
	 */
	public List<Emprestimo> getListaEmprestimosDoEmprestador() {
		return listaEmprestimosDoEmprestador;
	}
	
	/**
	 * Retorna a lista de emprestimos cotendo os emprestimos do beneficiador e do emprestador.
	 * @return A lista de emprestimos.
	 */
	public List<Emprestimo> getListaEmprestimosDeTodosStatus() {
		
		return listaEmprestimosDeTodosStatus;
	}
	/**
	 * Retorna a lista de emprestimos que ainda nao foram aprovados, ou seja, que estao pendentes.
	 * @return A lista de emprestimos nao aprovados.
	 */
	public List<Emprestimo> getListaEmprestimosPendentes() {
		return listaEmprestimosPendentes;
	}
	
	public List<Emprestimo> getEmprestimos(String campo) throws Exception{
		if(campo.equals("todos")){
			return getListaEmprestimosDeTodosStatus();
		}else if(campo.equals("emprestador")){
			return getListaEmprestimosDoEmprestador();
		}else if(campo.equals("beneficiado")){
			return getListaEmprestimosDoBeneficiado();
		}else{
			throw new Exception("Informe um campo valido");
		}
	}
	

 

	/**
	 * Compara dois objetos do tipo Usuario pelo login.
	 * @return true - Se os usuarios tiverem mesmo login.
	 * 		   false - Caso contrario.
	 */
	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof Usuario)){
			return false;
		}
		Usuario outro = (Usuario) obj;
		return this.getLogin().equals(outro.getLogin());
			
	}
}
